package project.documents.file;
/*
 * 待完成：用MVC模式分开DB和Action操作
 * 增删改查看导印统功能的实现
 */

import project.documents.dao.Data;
import project.documents.dao.DocumentDao;
import project.documents.dao.MyExcel;
import jxl.write.WriteException;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.json.JSONException;
import org.json.JSONObject;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.*;

public class ServletAction extends HttpServlet {
    String module="file";
    String sub="static";
    public void showDebug(String msg){
        System.out.println("["+(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date())+"]["+module+"/"+sub+"/ServletAction]"+msg);
    }
    /*
     * 处理顺序：先是service，后根据情况doGet或者doPost
     */
    public void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        processAction(request,response);
    }
    /*========================================函数分流 开始========================================*/
    public void processAction(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        HttpSession session = request.getSession();
        request.setCharacterEncoding("UTF-8");
        String action = request.getParameter("action");
        boolean actionOk = false;
        int resultCode=0;
        String resultMsg="ok";
        JSONObject json=new JSONObject();
        showDebug("processAction收到的action是："+action);
        if (action == null){
            resultMsg="传递过来的action是NULL";
        }else{
            //这几个常规增删改查功能
            if (action.equals("get_file_information_record")) {
                actionOk=true;
                try {
                    getFileRecord(request, response, json);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (action.equals("add_file_information_record")) {
                actionOk=true;
                try {
                    addFileInfRecord(request, response, json);
                } catch (JSONException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (action.equals("modify_File_record")) {
                actionOk=true;
                try {
                    modifyFileRecord(request, response, json);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (action.equals("delete_File_record")) {
                actionOk=true;
                try {
                    deleteFileRecord(request, response, json);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (action.equals("export_File_Information_record")) {
                actionOk=true;
                try {
                    exportFileRecord(request, response, json);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (action.equals("query_file_information_record")) {
                actionOk=true;
                try {
                    QueryFileRecord(request, response, json);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (action.equals("get_file_information_by_someType")) {
                actionOk=true;
                try {
                    getFileInfBySomeType(request, response, json);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (action.equals("upload_file_record")) {
                actionOk=true;
                try {
                    uploadFileRecord(request, response, json);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (action.equals("Get_File_Path")) {
                actionOk=true;
                try {
                    GetFilePath(request, response, json);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            try {
                responseBack(request,response,json);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }


    /*========================================函数分流 结束========================================*/
    /*========================================公共函数 开始========================================*/
    private Data getPageParameters(HttpServletRequest request, HttpServletResponse response, JSONObject json) throws JSONException {
        Data data=new Data();
        HttpSession session = request.getSession();
        /*----------------------------------------获取所有表单信息 开始----------------------------------------*/
        showDebug("[getPageParameters]----------------------------------------获取所有表单信息 开始----------------------------------------");
        JSONObject param=data.getParam();
        Enumeration requestNames=request.getParameterNames();
        for(Enumeration e=requestNames;e.hasMoreElements();){
            String thisName=e.nextElement().toString();
            String thisValue=request.getParameter(thisName);
            showDebug("[getPageParameters]"+thisName+"="+thisValue);
            showDebug(data.getParam().toString());
            param.put(thisName, thisValue);
        }
        String[] ids=request.getParameterValues("ids[]");if(ids!=null){param.put("ids[]",ids);}			//后头用这样来取出：String[] ids=(String[])(data.getParam().get("ids[]"));
        showDebug("[getPageParameters]----------------------------------------获取所有表单信息 完毕----------------------------------------");
        /*----------------------------------------获取所有表单信息 完毕----------------------------------------*/
        return data;
    }
    private void responseBack(HttpServletRequest request, HttpServletResponse response, JSONObject json) throws JSONException {
        boolean isAjax=true;if (request.getHeader("x-requested-with") == null || request.getHeader("x-requested-with").equals("com.tencent.mm")){isAjax=false;}	//判断是异步请求还是同步请求，腾讯的特殊
        if(isAjax){
            response.setContentType("application/json; charset=UTF-8");
            try {
                response.getWriter().print(json);
                response.getWriter().flush();
                response.getWriter().close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }else{
            String action=json.getString("action");
            String errorNo="0";
            String errorMsg="ok";
            String url = module+"/"+sub+"/result.jsp?action="+action+"&result_code="+errorNo+ "&result_msg=" + errorMsg;
            try {
                response.sendRedirect(url);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    /*========================================公共函数 结束========================================*/
    /*========================================CRUD业务函数 开始========================================*/
    private void uploadFileRecord(HttpServletRequest request, HttpServletResponse response, JSONObject json) throws JSONException, SQLException, UnsupportedEncodingException {
        Data data=getPageParameters(request,response,json);
        uploadFileRecord(request,data,json);
        DocumentDao dao=new DocumentDao();
        dao.saveUploadFileRecord(data,json);
    }

    private void uploadFileRecord(HttpServletRequest request, Data data, JSONObject json) throws UnsupportedEncodingException, JSONException {
        String resultMsg="ok";
        int resultCode=0;
        String title=null;
        String limitTime=null;
        String rootPath = this.getServletContext().getRealPath("/");//获取当前文件的绝对路径
        String savePath = "/";
        String downloadUrl="";                              //传到前端的下载链接
        List jsonFile=new ArrayList();
        HashMap<String, String> extMap = new HashMap<String, String>();
        extMap.put("file", "doc,docx,pdf,txt,xml,xls,xlsx,xml,ppt,pptx,jpg,png,csv,mp4,fbr");//设置上传文件到文件夹file下，文件类型只能为doc docx...这几类
        long maxSize = 1000000000;//设置上传的文件大小最大为1000000000
        boolean temp= ServletFileUpload.isMultipartContent(request);

        if(ServletFileUpload.isMultipartContent(request)){
            File uploadDir = new File(rootPath+savePath);//new一个file 路径为rootPath-savePath
            showDebug("程序自动生成的文件路径是"+rootPath+savePath);
            // .isDirectory()是检查一个对象是否是文件夹
            if(!uploadDir.isDirectory()){
                // mkdirs是新建文件夹，建立文件夹的原则是：如果父文件夹不存在并且最后一级子文件夹不存在，
                // 它就自动新建所有路经里写的文件夹；如果父文件夹存在，它就直接在已经存在的父文件夹下新建子文件夹。
                uploadDir.mkdirs();
            }
            if(!uploadDir.canWrite()){//上传目录file是否有写入的权限
                resultMsg = "1";//上传目录没有写权限
            }else{
                String dirName = "file";//设置上传目录为file
                if(!extMap.containsKey(dirName)){//判断上传目录是否正确
                    resultMsg = "2";//目录名不正确
                }else{
                    savePath += dirName + "/";
                    File saveDirFile = new File(rootPath+savePath);
                    if (!saveDirFile.exists()) {
                        saveDirFile.mkdirs();
                    }
                    File dirFile = new File(rootPath+savePath);
                    if (!dirFile.exists()) {
                        dirFile.mkdirs();
                    }
                    DiskFileItemFactory factory = new DiskFileItemFactory();
                    ServletFileUpload upload = new ServletFileUpload(factory);
                    upload.setHeaderEncoding("UTF-8");
                    List items = null;
                    try {
                        items = upload.parseRequest(request);
                    } catch (FileUploadException e) {
                        e.printStackTrace();
                    }
                    Iterator itr = items.iterator();
                    while (itr.hasNext()) {
                        FileItem item = (FileItem) itr.next();
                        String fileName = item.getName();
                        long fileSize = item.getSize();
                        if (!item.isFormField()) {
                            //检查文件大小
                            if(item.getSize() > maxSize){
                                resultMsg = "3";//上传文件大小超过限制
                            }else{
                                showDebug("[file_upload]fileName="+fileName);
                                String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
                                if(!Arrays.<String>asList(extMap.get(dirName).split(",")).contains(fileExt)){
                                    resultMsg = "4";//上传文件扩展名是不允许的扩展名
                                }else{
                                    SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
                                    String newFileName = df.format(new Date()) + "_" + new Random().nextInt(1000) + "." + fileExt;
                                    try{
                                        File uploadedFile = new File(rootPath+savePath, newFileName);
                                        item.write(uploadedFile);
                                        downloadUrl = savePath+newFileName;
                                        resultMsg = "5";//上传文件成功
                                        //写数据库准备
                                        HashMap map=new HashMap();
                                        map.put("download_url",downloadUrl);
                                        map.put("file_name",newFileName);
                                        map.put("file_path",rootPath+savePath+newFileName);
                                        jsonFile.add(map);
                                    }catch(Exception e){
                                        resultMsg = "6";//上传文件失败
                                    }
                                }
                            }
                        }else{
                            // 这是同步跳转的方式，才会用到这部分；否则用的异步方式，就是上面那部分
                            //如果是FormField，就是前端的device_id,device_name这些
                            String fieldName=item.getFieldName();
                            String fieldValue=item.getString("UTF-8");
                            showDebug("[upload_file_record][form_field]fieldName="+fieldName+"，fieldValue="+fieldValue);
                            if(fieldName.equals("title")){title=fieldValue;};
                            if(fieldName.equals("limit_time")){limitTime=fieldValue;};
                        }
                    }
                }
            }
        }
        showDebug("[uploadFileRecord]download_url="+downloadUrl+"&result_code="+resultCode+"&resultMsg="+resultMsg);
        //然后返回给前端
        json.put("result_code",0);
        json.put("result_msg","ok");
        json.put("files", jsonFile);
        json.put("download_url",downloadUrl);
    }

    private void DeleteFileRecord(HttpServletRequest request, Data data, JSONObject json) throws UnsupportedEncodingException, JSONException {
        String resultMsg="";
        int resultCode=0;

        // 1.获得请求文件名
        String filerelativepath = request.getParameter("fileRelativePath");
        int length=filerelativepath.length();
        filerelativepath=filerelativepath.substring(1,length);
        // 去掉绝对路径前的"/",换为"\"
        filerelativepath=filerelativepath.replaceAll("/","\\\\");
        //获取当前文件的绝对路径
        String rootPath = this.getServletContext().getRealPath("/");
        // 3.获取该文件所在路径
        String filePath = rootPath + filerelativepath;
        showDebug("构造的绝对路径是rootPath="+rootPath+" ,文件相对路径是filerelativepath="+filerelativepath+" , 总路径是filepath="+filePath);
        // 4.在指定路径下创建指定名称的文件
        File deleteFile = new File (filePath) ;
        boolean flag = false;
        if (deleteFile.exists()) {
            flag = deleteFile.delete();
            if (flag) {
                resultMsg="ok";
                showDebug("删除成功！");
            } else {
                resultMsg="no";
                showDebug("删除失败！");
            }
        }
        else {
            resultMsg="文件不存在！";
            showDebug("文件不存在！");
        }

        // 6.返回客户端操作信息
        json.put("result_code",resultCode);
        json.put("result_msg",resultMsg);

    }


    private void getFileRecord(HttpServletRequest request, HttpServletResponse response, JSONObject json) throws JSONException, SQLException {
        DocumentDao dao=new DocumentDao();
        Data data=getPageParameters(request,response,json);
        dao.getFileRecord(data,json);
    }
    private void modifyFileRecord(HttpServletRequest request, HttpServletResponse response, JSONObject json) throws JSONException, SQLException, UnsupportedEncodingException {
        DocumentDao dao=new DocumentDao();
        Data data=getPageParameters(request,response,json);
        dao.modifyFileRecord(data,json);
    }
    private void deleteFileRecord(HttpServletRequest request, HttpServletResponse response, JSONObject json) throws JSONException, SQLException, UnsupportedEncodingException {

        Data data=getPageParameters(request,response,json);
        showDebug("执行入了中的删除操作，即将进入文件删除！");
        DeleteFileRecord(request,data,json);
        // operation_result为获取实际去删除文件的结果，结果是删除成功（ok），删除失败（no），文件不存在（文字信息）
        String operation_result=json.getString("result_msg");
        if(operation_result=="ok") {
            DocumentDao dao = new DocumentDao();
            showDebug("文件实际已经删除，准备删除记录");
            dao.deleteFileRecord(data, json);
        }
    }
    private void addFileInfRecord(HttpServletRequest request, HttpServletResponse response, JSONObject json) throws JSONException, SQLException {
        DocumentDao dao=new DocumentDao();
        Data data=getPageParameters(request,response,json);
        dao.addFileInfRecord(data,json);
    }
    /*========================================CRUD业务函数 结束========================================*/
    private void QueryFileRecord(HttpServletRequest request, HttpServletResponse response, JSONObject json) throws JSONException, SQLException {
        DocumentDao dao=new DocumentDao();
        Data data=getPageParameters(request,response,json);
        dao.getFileRecord(data,json);
    }


    private void exportFileRecord(HttpServletRequest request, HttpServletResponse response, JSONObject json) throws JSONException, SQLException, IOException, WriteException {
        DocumentDao dao=new DocumentDao();
        Data data=getPageParameters(request,response,json);
        dao.getFileRecord(data,json);
        getExportFileRecordToFile(json,data);
        getExportFileRecordToExcel(json,data);
        getExportFileRecordToPDF(json,data);
        getExportFileRecordToTxt(json,data);
    }

    private void getExportFileRecordToTxt(JSONObject json, Data data) {

    }

    private void getExportFileRecordToPDF(JSONObject json, Data data) {

    }

    private void getExportFileRecordToExcel(JSONObject json, Data data) throws WriteException, IOException, JSONException {
        //获取当前文件的绝对路径
        String rootPath = this.getServletContext().getRealPath("/");
        String savePath="/file/";
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
        String newFileName = df.format(new Date()) + "_" + "export_excel_file_information.xls";
        // 创建自定义的excel
        MyExcel excel=new MyExcel(rootPath+savePath+newFileName);
        json.put("download_url","../"+savePath+newFileName);
        json.put("file_path",savePath+newFileName);
        excel.exportData(data,json);
    }

    private void getExportFileRecordToFile(JSONObject json, Data data) throws JSONException {
        // Map数据转化为Json，再转换为String
        String jsonStr = json.toString();
        //获取当前文件的绝对路径
        String rootPath = this.getServletContext().getRealPath("/");
        String savePath="/file/";
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
        String newFileName = df.format(new Date()) + "_" + "export_File_Information.txt";
        File jsonFile = new File(rootPath+savePath,newFileName);
        // 注意：一下的download_url后的字符串前必须带有“/”，否则就是在本地寻找那个路径，会发现找不到这个项目文件
        json.put("download_url",savePath+newFileName);
        try {
            // 文件不存在就创建文件
            if (!jsonFile.exists()) {
                jsonFile.createNewFile();
            }
            FileWriter fileWriter = new FileWriter(jsonFile.getAbsoluteFile());
            BufferedWriter bw = new BufferedWriter(fileWriter);
            bw.write(jsonStr);
            bw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void getFileInfBySomeType(HttpServletRequest request, HttpServletResponse response, JSONObject json) throws JSONException, SQLException {
        DocumentDao dao=new DocumentDao();
        Data data=getPageParameters(request,response,json);
        dao.getFileInfBySomeType(data,json);

    }
    private void GetFilePath(HttpServletRequest request, HttpServletResponse response, JSONObject json) throws JSONException, SQLException {
        DocumentDao dao=new DocumentDao();
        Data data=getPageParameters(request,response,json);
        dao.getFilePath(data,json);
    }
}

